package admin

import (
	"drama-go/internal/models/model"
	"drama-go/internal/models/query"
	"drama-go/internal/module/admin/dto/drama"
	"drama-go/internal/module/constant"
	"github.com/gin-gonic/gin"
	"github.com/worryry/8-pigeons/pkg/database/mysql"
	"github.com/worryry/8-pigeons/pkg/server/errcode"
	"github.com/worryry/8-pigeons/pkg/server/httpServer/response"
	"github.com/worryry/8-pigeons/pkg/server/router"
	"github.com/worryry/8-pigeons/pkg/setting"
	"strings"
)

func init() {
	router.Register(&Drama{})
}

type Drama struct {
}

func (d Drama) List(c *gin.Context) {
	q := query.Drama.WithContext(c)
	var params drama.Page
	if err := c.ShouldBind(&params); err != nil {
		response.ToErrResponse(c, errcode.InvalidParams.WithDetails(err.Error()))
		return
	}
	if params.Limit == 0 {
		params.Limit = 20
	}
	if params.ID > 0 {
		q = q.Where(query.Drama.ID.Eq(params.ID))
	}

	dramas, i, err := q.FindByPage(params.Offset, params.Limit)

	for k, drama := range dramas {
		if !strings.Contains(drama.Cover, "http") {
			dramas[k].Cover = setting.GetString("server.storage") + drama.Cover
		}
	}

	if err != nil {
		response.ToErrResponse(c, errcode.NotFound.WithDetails(err.Error()))
		return
	}
	response.ToList(c, response.List{
		Total: int32(i),
		List:  dramas,
	})
	return
}

func (d Drama) Create(c *gin.Context) {
	var params drama.Create
	if err := c.ShouldBind(&params); err != nil {
		response.ToErrResponse(c, errcode.InvalidParams.WithDetails(err.Error()))
		return
	}
	q := query.Drama
	err := q.Select(q.Name, q.Cover, q.Description, q.Origin, q.Duration, q.Score, q.Difficulty).Create(&model.Drama{
		Name:        params.Name,
		Cover:       params.Cover,
		Description: params.Description,
		Origin:      params.Origin,
		Duration:    params.Duration,
		Score:       params.Score,
		Difficulty:  params.Difficulty,
	})
	if err != nil {
		response.ToErrResponse(c, errcode.BusinessError.WithDetails(err.Error()))
		return
	}
	response.ToSuccess(c, nil)
	return
}

func (d Drama) Role(c *gin.Context) {
	var params drama.Role
	if err := c.ShouldBind(&params); err != nil {
		response.ToErrResponse(c, errcode.InvalidParams.WithDetails(err.Error()))
		return
	}

	dr := query.Drama
	dra, err := dr.Where(dr.ID.Eq(params.DramaId)).First()
	if err != nil {
		response.ToErrResponse(c, errcode.InvalidParams.WithDetails("剧本不存在"))
		return
	}
	t := query.Use(mysql.DB)
	//事务
	err = t.Transaction(func(tx *query.Query) error {
		q := query.Role
		err = q.Select(q.Name, q.Cover, q.Description, q.DramaID, q.Gender).Create(&model.Role{
			Name:        params.Name,
			Cover:       params.Cover,
			Description: params.Description,
			DramaID:     params.DramaId,
			Gender:      params.Gender,
		})
		if err != nil {
			return err
		}
		//修改剧本角色统计信息
		if params.Gender == constant.DramaGenderMan {
			dra.WomenNr++
		} else if params.Gender == constant.DramaGenderWoman {
			dra.MenNr++
		}
		dra.TotalNr++
		_, err = dr.Where(dr.ID.Eq(params.DramaId)).Updates(model.Drama{WomenNr: dra.WomenNr, MenNr: dra.MenNr, TotalNr: dra.TotalNr})
		if err != nil {
			return err
		}
		return nil
	})
	if err != nil {
		response.ToErrResponse(c, errcode.BusinessError.WithDetails(err.Error()))
		return
	}

	response.ToSuccess(c, nil)
	return
}

func (d Drama) GetRoles(c *gin.Context) {
	var params drama.GetRoles
	if err := c.ShouldBind(&params); err != nil {
		response.ToErrResponse(c, errcode.InvalidParams.WithDetails(err.Error()))
		return
	}

	q := query.Role
	roles, err := q.Where(q.DramaID.Eq(params.DramaId)).Find()
	if err != nil {
		response.ToErrResponse(c, errcode.NotFound.WithDetails(err.Error()))
		return
	}
	for k, role := range roles {
		if !strings.Contains(role.Cover, "http") {
			roles[k].Cover = setting.GetString("server.storage") + role.Cover
		}
	}
	response.ToSuccess(c, roles)
}

func (d Drama) AddContent(c *gin.Context) {
	var params drama.AddContent
	if err := c.ShouldBind(&params); err != nil {
		response.ToErrResponse(c, errcode.InvalidParams.WithDetails(err.Error()))
		return
	}
	q := query.Content
	err := q.Select(q.RoleID, q.Step, q.Content).Create(&model.Content{
		RoleID:  params.RoleId,
		Step:    params.Step,
		Content: params.Content,
	})
	if err != nil {
		response.ToErrResponse(c, errcode.BusinessError.WithDetails(err.Error()))
		return
	}
	response.ToSuccess(c, nil)
	return
}

func (d Drama) EditContent(c *gin.Context) {
	var params drama.EditContent
	if err := c.ShouldBind(&params); err != nil {
		response.ToErrResponse(c, errcode.InvalidParams.WithDetails(err.Error()))
		return
	}
	q := query.Content
	_, err := q.Where(q.ID.Eq(params.ID)).Updates(model.Content{
		Content: params.Content,
	})
	if err != nil {
		response.ToErrResponse(c, errcode.BusinessError.WithDetails(err.Error()))
		return
	}
	response.ToSuccess(c, nil)
	return
}

func (d Drama) GetContent(c *gin.Context) {
	var params drama.GetContent
	if err := c.ShouldBind(&params); err != nil {
		response.ToErrResponse(c, errcode.InvalidParams.WithDetails(err.Error()))
		return
	}
	q := query.Content.WithContext(c)
	if params.Step > 0 {
		q = q.Where(query.Content.Step.Eq(params.Step))
	}
	content, err := q.Where(query.Content.RoleID.Eq(params.RoleId)).First()
	if err != nil {
		response.ToSuccess(c, content)
		return
	}
	response.ToSuccess(c, content)
	return
}
